package it.myAndroid.ShadowSMS;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.GregorianCalendar;

import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneNumberUtils;
import android.util.Log;


/**
 * @author stefazzi
 * @date 19/feb/2013
 * @version 
 */
public class ShadowSMSSmsSend 
{
	private Intent broadcastIntent;
	private Context aContext;
	
	public ShadowSMSSmsSend(final Context context) 
	{
		aContext = context;
	}
	
	public void sendSms(String sender, String body) 
	{
  	//Source: http://stackoverflow.com/a/12338541
    //Source: http://blog.dev001.net/post/14085892020/android-generate-incoming-sms-from-within-your-app
		byte [] pdu = null ;
    byte [] scBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD( "0000000000" );
    byte [] senderBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(sender);
    int lsmcs = scBytes.length;
    byte [] dateBytes = new byte [ 7 ];
    Calendar calendar = new GregorianCalendar();
    dateBytes[ 0 ] = reverseByte(( byte ) (calendar.get(Calendar.YEAR)));
    dateBytes[ 1 ] = reverseByte(( byte ) (calendar.get(Calendar.MONTH) + 1 ));
    dateBytes[ 2 ] = reverseByte(( byte ) (calendar.get(Calendar.DAY_OF_MONTH)));
    dateBytes[ 3 ] = reverseByte(( byte ) (calendar.get(Calendar.HOUR_OF_DAY)));
    dateBytes[ 4 ] = reverseByte(( byte ) (calendar.get(Calendar.MINUTE)));
    dateBytes[ 5 ] = reverseByte(( byte ) (calendar.get(Calendar.SECOND)));
    dateBytes[ 6 ] = reverseByte(( byte ) ((calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / ( 60 * 1000 * 15 )));
    try 
    {
    	ByteArrayOutputStream bo = new ByteArrayOutputStream();
      bo.write(lsmcs);
      bo.write(scBytes);
      bo.write( 0x04 );
      bo.write(( byte ) sender.length());
      bo.write(senderBytes);
      bo.write( 0x00 );
      bo.write( 0x00 );  // encoding: 0 for default 7bit
      bo.write(dateBytes);
      try 
      {
        String sReflectedClassName = "com.android.internal.telephony.GsmAlphabet";
        Class cReflectedNFCExtras = Class.forName(sReflectedClassName);
        Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod("stringToGsm7BitPacked", new Class[] { String.class });
        stringToGsm7BitPacked.setAccessible(true);
        byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null,body);
        bo.write(bodybytes);
      } 
      catch(Exception e) 
      {
  			Log.e(ShadowSMSSmsSend.class.getName(),"Error",e);
  			broadcastIntent = new Intent();
  			broadcastIntent.setAction("SMS_RECEIVED_ERROR");
  			aContext.sendBroadcast(broadcastIntent);        	
      }
      pdu = bo.toByteArray();
      } 
      catch (IOException e) 
      {
  			Log.e(ShadowSMSSmsSend.class.getName(),"Error",e);
  			broadcastIntent = new Intent();
  			broadcastIntent.setAction("SMS_RECEIVED_ERROR");
  			aContext.sendBroadcast(broadcastIntent);        
      }
    	try
    	{
    		broadcastIntent = new Intent(); 
    		//broadcastIntent = new Intent("com.android.mms.transaction.SEND_MESSAGE");
    		broadcastIntent.setClassName("com.android.mms" ,"com.android.mms.transaction.SmsReceiverService");
    		broadcastIntent.setAction( "android.provider.Telephony.SMS_RECEIVED" );
    		broadcastIntent.putExtra( "pdus" , new Object[] { pdu });
    		broadcastIntent.putExtra( "format", "3gpp");
	      aContext.startService(broadcastIntent);

    	}
    	catch (Exception e)
    	{
  			Log.e(ShadowSMSSmsSend.class.getName(),"Error",e);
  			broadcastIntent = new Intent();
  			broadcastIntent.setAction("SMS_RECEIVED_ERROR");
  			aContext.sendBroadcast(broadcastIntent);        
    	}
	}
	
	private byte reverseByte( byte b) 
	{
    return ( byte ) ((b & 0xF0 ) >> 4 | (b & 0x0F ) << 4 );
	}
	
}
